home *** CD-ROM | disk | FTP | other *** search
/ Aminet 45 / Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso / Aminet / dev / gui / FoxGuiSource.lha / FoxLibSource / Display.c < prev    next >
C/C++ Source or Header  |  2001-07-07  |  9KB  |  322 lines

  1. /* FoxGUI - The fast, flexible, free Amiga GUI system
  2.     Copyright (C) 2001 Simon Fox (Foxysoft)
  3.  
  4. This library is free software; you can redistribute it and/ormodify it under the terms of the GNU Lesser General PublicLicense as published by the Free Software Foundation; eitherversion 2.1 of the License, or (at your option) any later version.This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULesser General Public License for more details.You should have received a copy of the GNU Lesser General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  5. Foxysoft: www.foxysoft.co.uk      Email:simon@foxysoft.co.uk                */
  6.  
  7. /******************************************************************************
  8.  * Shared library code.  Cannot call functions which use exit() such as:
  9.  * printf(), fprintf()
  10.  *
  11.  * Otherwise:
  12.  * The linker returns "__XCEXIT undefined" and the program will fail.
  13.  * This is because you must not exit() a library!
  14.  *
  15.  * Also:
  16.  * proto/exec.h must be included instead of clib/exec_protos.h and
  17.  * __USE_SYSBASE must be defined.
  18.  *
  19.  * Otherwise:
  20.  * The linker returns "Absolute reference to symbol _SysBase" and the
  21.  * library crashes.  Presumably the same is true for the other protos.
  22.  ******************************************************************************/
  23.  
  24. #define __USE_SYSBASE
  25.  
  26. #include <proto/mathieeedoubbas.h>
  27. #include <string.h>
  28.  
  29. #include <proto/graphics.h>
  30. #include <proto/intuition.h>
  31. #include <graphics/display.h>
  32. #include <graphics/displayinfo.h>
  33.  
  34. #include "/FoxInclude/foxgui.h"
  35. #include "FoxGuiTools.h"
  36.  
  37. struct Modes
  38. {
  39.     char *ModeName;
  40.     unsigned long key;
  41.     long width, height;
  42. };
  43.  
  44. int nA500Modes = 4;
  45. struct Modes A500Modes[] = { NULL, INVALID_ID, 0, 0, 
  46.                                     "Low Res", LORES_KEY, 320, 200, 
  47.                                     "High Res", HIRES_KEY, 640, 200, 
  48.                                     "Low Res Laced", LORES_KEY | INTERLACE, 320, 400,
  49.                                     "High Res Laced", HIRES_KEY | INTERLACE, 640, 400,
  50.                                     NULL, INVALID_ID, 0, 0 };
  51.  
  52. unsigned long FOXLIB GetNextAvailableDisplayMode(REGD0 unsigned long previous)
  53. {
  54.     if (Gui.LibVersion >= 36)
  55.     {
  56.         unsigned long error, retval = INVALID_ID;
  57.  
  58.         do
  59.         {
  60.             retval = NextDisplayInfo(previous);
  61.             previous = retval;
  62.             error = ModeNotAvailable(retval);
  63.         }    while (error != 0 && retval != INVALID_ID);
  64.         return retval;
  65.     }
  66.     else
  67.     {
  68.         int i = 0;
  69.  
  70.         while (A500Modes[i].key != previous && i < nA500Modes + 2)
  71.             i++;
  72.         if (i == nA500Modes + 2)
  73.             return INVALID_ID;
  74.         return A500Modes[i + 1].key;
  75.     }
  76. }
  77.  
  78. static GuiWindow *gwDisplayList;
  79. static unsigned long *DisplayModeList;
  80. static PushButton *pbOkay;
  81. static ListBox *lbDisplay;
  82. static unsigned long modeselected;
  83. static BOOL retval;
  84.  
  85. static int __far __stdargs CloseFn(GuiWindow *gw, int event, int x, int y, void *data)
  86. {
  87.     if (event == GW_CLOSE)
  88.     {
  89.         retval = FALSE;
  90.         if (DisplayModeList)
  91.             GuiFree(DisplayModeList);
  92.         DisplayModeList = NULL;
  93.         DestroyWinButtons(gw, FALSE);
  94.         DestroyWinListBoxes(gw, FALSE);
  95.         CloseGuiWindow(gw);
  96.         return GUI_CANCEL | GUI_MODAL_END;
  97.     }
  98.     return GUI_MODAL_END;
  99. }
  100.  
  101. static int __far __stdargs CancelFn(PushButton *pb)
  102. {
  103.     CloseFn(gwDisplayList, GW_CLOSE, 0, 0, NULL);
  104.     return GUI_MODAL_END;
  105. }
  106.  
  107. static int __far __stdargs OkayFn(PushButton *pb)
  108. {
  109.     if (Gui.LibVersion >= 36)
  110.         modeselected = DisplayModeList[HiNum(lbDisplay) - 1];
  111.     else
  112.         modeselected = A500Modes[HiNum(lbDisplay)].key;
  113.     CloseFn(gwDisplayList, GW_CLOSE, 0, 0, NULL);
  114.     retval = TRUE;
  115.     return GUI_MODAL_END;
  116. }
  117.  
  118. static int __far __stdargs lbEventFn(ListBox *lb, short event, int itemno, void **data)
  119. {
  120.     if (event == LB_DBLCLICK)
  121.         return OkayFn(pbOkay);
  122.     else if (event == LB_SELECT || event == LB_CURSOR)
  123.         EnableButton(pbOkay);
  124.     return GUI_CONTINUE;
  125. }
  126.  
  127. BOOL FOXLIB GetModeSize(REGD0 unsigned long displaymode, REGA0 long *width, REGA1 long *height)
  128. {
  129.     unsigned long result;
  130.     struct DimensionInfo dim;
  131.  
  132.     if (Gui.LibVersion >= 36)
  133.     {
  134.         result = GetDisplayInfoData(NULL, (UBYTE *) &dim, sizeof(dim), DTAG_DIMS, displaymode);
  135.         if (result)
  136.         {
  137.             if (width)
  138.                 *width = dim.Nominal.MaxX;
  139.             if (height)
  140.                 *height = dim.Nominal.MaxY;
  141.             return TRUE;
  142.         }
  143.     }
  144.     else
  145.     {
  146.         int i = 1;
  147.         while (A500Modes[i].key != displaymode && A500Modes[i].key != INVALID_ID)
  148.             i++;
  149.         if (width)
  150.             *width = A500Modes[i].width;
  151.         if (height)
  152.             *height = A500Modes[i].height;
  153.         return TRUE;
  154.     }
  155.     return FALSE;
  156. }
  157.  
  158. int FOXLIB GetModeName(REGD0 unsigned long displaymode, REGA0 char *buffer, REGD1 int buflen)
  159. {
  160.     struct NameInfo nInfo;
  161.     char *name;
  162.  
  163.     if (Gui.LibVersion >= 36)
  164.     {
  165.         if (GetDisplayInfoData(NULL, (UBYTE *) &nInfo, sizeof(nInfo), DTAG_NAME, displaymode))
  166.             name = nInfo.Name;
  167.         else
  168.             name = NULL;
  169.     }
  170.     else
  171.     {
  172.         int i = 1;
  173.         while (A500Modes[i].key != displaymode && A500Modes[i].key != INVALID_ID)
  174.             i++;
  175.         name = A500Modes[i].ModeName;
  176.     }
  177.  
  178.     if (!name)
  179.         buffer[0] = '\0';
  180.     else
  181.     {
  182.         if (strlen(name) >= buflen)
  183.         {
  184.             strncpy(buffer, name, buflen - 1);
  185.             buffer[buflen - 1] = '\0';
  186.         }
  187.         else
  188.             strcpy(buffer, name);
  189.         return (int) (strlen(name) + 1);
  190.     }
  191.     return 0;
  192. }
  193.  
  194. BOOL FOXLIB ShowDisplayList(REGA0 void *Scr, REGA1 char *title, REGD0 int DPen, REGD1 int BPen,
  195.         REGA2 unsigned long *displayModeID)
  196. {
  197.     if (Scr)
  198.     {
  199.         int twp;
  200.  
  201.         modeselected = 0;
  202.         if (ISGUISCREEN(Scr))
  203.         {
  204.             GuiScreen *sc = (GuiScreen *) Scr;
  205.             twp = TopWindowPixel(sc->scr, NULL);
  206.             gwDisplayList = CreateGuiWindow(sc, sc->scr, 144, 18, 312, 100 + twp, DPen, BPen, title, GW_CLOSE | GW_DRAG | GW_DEPTH | GW_SIZE, CloseFn);
  207.         }
  208.         else if (Gui.LibVersion >= 36)
  209.         {
  210.             // Scr is not a FoxGui screen so it must be the name of a public screen to open on.
  211.             struct Screen *PubScr = LockPubScreen((char *) Scr);
  212.             if (!PubScr)
  213.                 return FALSE;
  214.             twp = TopWindowPixel(PubScr, NULL);
  215.             gwDisplayList = CreateGuiWindow(NULL, PubScr, 144, 18, 312, 100 + twp, DPen, BPen, title, GW_CLOSE | GW_DRAG | GW_DEPTH | GW_SIZE, CloseFn);
  216.             UnlockPubScreen((char *) Scr, PubScr);
  217.         }
  218.         else
  219.             gwDisplayList = NULL;
  220.         if (gwDisplayList)
  221.         {
  222.             long longest = 0;
  223.             struct NameInfo nInfo;
  224.             PushButton *pbCancel;
  225.             unsigned long DisplayMode = INVALID_ID;
  226.             int buttonwidth;
  227.             struct IntuiText it;
  228.             int items = 0;
  229.  
  230.             DisplayModeList = NULL;
  231.  
  232.             it.IText = "Cancel"; // the underlined C shouldn't make it noticably longer
  233.             if (gwDisplayList->ParentScreen->Font)
  234.                 it.ITextFont = gwDisplayList->ParentScreen->Font;
  235.             else
  236.                 it.ITextFont = &GuiFont;
  237.             buttonwidth = IntuiTextLength(&it) + 10;
  238.  
  239.             lbDisplay = MakeListBox(gwDisplayList, 7, twp + 1, 280, 77, 2, 2, LB_DBLCLICK | LB_SELECT | LB_CURSOR | S_AUTO_SIZE, lbEventFn, NULL);
  240.             pbCancel = MakeButton(gwDisplayList, "_Cancel", 7, twp + 82, buttonwidth, 14, 'c', NULL, CancelFn, BN_CLEAR | BN_STD | S_AUTO_SIZE, NULL);
  241.             pbOkay = MakeButton(gwDisplayList, "_Okay", 287 - buttonwidth, twp + 82, buttonwidth, 14, 'o', NULL, OkayFn, BN_CLEAR | BN_STD | S_AUTO_SIZE, NULL);
  242.             DisableButton(pbOkay);
  243.             if ((!lbDisplay) || (!pbCancel) || (!pbOkay))
  244.             {
  245.                 CloseFn(gwDisplayList, GW_CLOSE, 0, 0, NULL);
  246.                 return FALSE;
  247.             }
  248.  
  249.             if (Gui.LibVersion >= 36)
  250.             {
  251.                 // Find the longest mode name
  252.                 do
  253.                 {
  254.                     DisplayMode = GetNextAvailableDisplayMode(DisplayMode);
  255.                     if (DisplayMode != INVALID_ID)
  256.                     {
  257.                         if (GetDisplayInfoData(NULL, (UBYTE *) &nInfo, sizeof(nInfo), DTAG_NAME, DisplayMode))
  258.                         {
  259.                             long len;
  260.                             it.IText = nInfo.Name;
  261.                             len = IntuiTextLength(&it);
  262.                             if (len > longest)
  263.                                 longest = len;
  264.                         }
  265.                     }
  266.                 } while (DisplayMode != INVALID_ID);
  267.                 SetListBoxTabStops(lbDisplay, FALSE, 1, longest + 4);
  268.  
  269.                 // Populate the list
  270.                 do
  271.                 {
  272.                     DisplayMode = GetNextAvailableDisplayMode(DisplayMode);
  273.                     if (DisplayMode != INVALID_ID)
  274.                     {
  275.                         unsigned long *newdml;
  276.                         struct DimensionInfo dInfo;
  277.                         char text[500];
  278.  
  279.                         if (GetDisplayInfoData(NULL, (UBYTE *) &dInfo, sizeof(dInfo), DTAG_DIMS, DisplayMode) &&
  280.                                 GetDisplayInfoData(NULL, (UBYTE *) &nInfo, sizeof(nInfo), DTAG_NAME, DisplayMode))
  281.                         {
  282.                             long width = dInfo.Nominal.MaxX - dInfo.Nominal.MinX + 1;
  283.                             long height = dInfo.Nominal.MaxY - dInfo.Nominal.MinY + 1;
  284.  
  285.                             sprintf(text, "%s\t(%ld, %ld)", nInfo.Name, width, height);
  286.                             items++;
  287.                             newdml = (unsigned long *) GuiMalloc(items * sizeof(unsigned long), 0);
  288.                             if (!newdml)
  289.                             {
  290.                                 CloseFn(gwDisplayList, GW_CLOSE, 0, 0, NULL);
  291.                                 return FALSE;
  292.                             }
  293.                             if (DisplayModeList)
  294.                             {
  295.                                 memcpy(newdml, DisplayModeList, (items - 1) * sizeof(unsigned long));
  296.                                 GuiFree(DisplayModeList);
  297.                                 DisplayModeList = newdml;
  298.                             }
  299.                             else
  300.                                 DisplayModeList = newdml;
  301.                             DisplayModeList[items - 1] = DisplayMode;
  302.  
  303.                             AddListBoxItem(lbDisplay, text, FALSE);
  304.                         }
  305.                     }
  306.                 } while (DisplayMode != INVALID_ID);
  307.             }
  308.             else
  309.             {
  310.                 int i;
  311.                 for (i = 1; A500Modes[i].ModeName != NULL; i++)
  312.                     AddListBoxItem(lbDisplay, A500Modes[i].ModeName, FALSE);
  313.             }
  314.             ListBoxRefresh(lbDisplay);
  315.             WinMsgLoop(gwDisplayList);
  316.             *displayModeID = modeselected;
  317.             return retval;
  318.         }
  319.     }
  320.     return FALSE;
  321. }
  322.